<script setup>
import {ref} from 'vue';
import {fileUpload, hello, md5, merge} from "@/api/file.js";
import {ElMessage} from "element-plus";

const files = ref([])
// const uploadUrl = ref('http://localhost:8080/uploadV2')
import CryptoJS from 'crypto-js';

const uploading = ref(false)
import MD5 from 'crypto-js/md5';

const percent = ref(0);
const upload = async (file) => {
  // 使用一个 flag 来控制是否需要上传文件
  let shouldUpload = false;
  const fileReader = new FileReader();
  return new Promise((resolve, reject) => {
    fileReader.onload = async function (e) {
      const arrayBuffer = e.target.result;

      // 将 ArrayBuffer 转换为 CryptoJS 支持的 WordArray
      const wordArray = CryptoJS.lib.WordArray.create(arrayBuffer);
      // 计算 MD5 值
      const fileMD5 = CryptoJS.MD5(wordArray).toString();

      try {
        // 假设 md5 是一个异步请求函数，返回文件秒传的响应
        const res = await md5({md5: fileMD5});
        if (res.code === 200) {
          // MD5 存在，直接返回，不上传文件
          ElMessage.success('文件秒传成功');
          resolve();  // 结束 Promise，跳过上传逻辑
        } else if (res.code === 500) {
          // MD5 不存在，设置标志，准备开始上传文件
          console.log('MD5 不存在，返回500，开始上传');
          shouldUpload = true;
          resolve();  // 继续执行上传逻辑
        }
      } catch (err) {
        // 如果请求失败（可能是网络错误等），也继续上传
        console.log('MD5 不存在，返回500，开始上传');
        shouldUpload = true;
        resolve();  // 继续执行上传
      }
    };
    // 读取文件内容
    fileReader.readAsArrayBuffer(file.raw.raw);
  }).then(async () => {
    // 如果需要上传，则执行分片上传
    if (shouldUpload) {
      const chunkSize = 1024 * 1024; // 每个块的大小为 1MB
      const fileSize = file.size;
      const chunks = Math.ceil(fileSize / chunkSize);  // 计算块数
      let uploaded = 0;
      const chunkPromises = []; // 用来存储每个分片上传的 Promise
      // 创建并行上传每个分片的任务
      for (let i = 0; i < chunks; i++) {
        const start = i * chunkSize;
        const end = Math.min(start + chunkSize, fileSize);
        // 构建表单数据
        const formData = new FormData();
        formData.append('fileID', file.uid);  // 文件ID
        formData.append('currentChunk', i);  // 当前块编号
        formData.append('totalChunk', chunks);  // 总块数
        formData.append('file', file.raw.raw.slice(start, end));  // 文件的当前块数据
        // 将每个分片上传的 Promise 添加到数组中
        chunkPromises.push(
            fileUpload(formData).then((res) => {
              if (res.code == 200) {
                uploaded++;
                percent.value = Math.floor((uploaded / chunks) * 100);  // 更新上传进度
              } else {
                throw new Error(`分片上传失败，分片 ${i}`);
              }
            })
        );
      }
      // 等待所有分片上传完成
      try {
        await Promise.all(chunkPromises);  // 并行上传所有分片
        console.log('文件上传成功');
        // 调用合并接口
        await mergeFile(file);  // 调用合并接口
      } catch (err) {
        console.error('文件上传失败:', err);
        ElMessage.error('文件上传失败！');
      }
    }
  });
};


const mergeFile = async (file) => {
  try {
    const res = await merge({fileID: file.uid, fileType: file.raw.raw.type, fileName: file.name})
    if (res.code === 200) {
      ElMessage.success('文件合并成功！');
    } else {
      ElMessage.error('文件合并失败！');
    }
  } catch (err) {
    console.error('合并文件请求失败:', err);
    ElMessage.error('文件合并失败！');
  }
};


// 上传处理
const handleUpload = async () => {
  try {
    uploading.value = true;  //控制进度条的
    for (let i = 0; i < files.value.length; i++) {
      const file = files.value[i];
      const res = await upload(file);  // 上传文件并获取 URL
      console.log('上传结果:', res);  // 打印上传的结果
    }
  } catch (err) {
    console.error('上传错误:', err);  // 打印错误信息
    ElMessage.error(`文件上传失败！${err.message}`);
  } finally {
    uploading.value = false;  // 上传结束
  }
};

const handleChange = (selectFiles) => {
  // 打印 selectFiles，查看它的内容
  console.log(selectFiles);

  // 确保 selectFiles 是一个数组，处理多文件选择
  const fileList = Array.isArray(selectFiles) ? selectFiles : [selectFiles];

  // 遍历所有文件，处理每个文件信息
  fileList.forEach(file => {
    const fileInfo = {
      name: file.name,  // 文件名
      size: file.size,  // 文件大小
      status: 'ready',  // 初始状态为 'ready'
      percentage: 0,    // 上传进度，初始为0
      raw: file,        // 原始文件对象
      uid: file.uid || Date.now()  // 使用文件的 uid 或者生成新的
    };

    // 将文件信息推入 files 数组
    files.value.push(fileInfo);
  });

  console.log(files.value);  // 打印 files 数组，检查其内容
};
const handleBeforeUpload = () => {

}
const handleProgress = (event, file) => {
  percent.value = Math.floor((event.loaded / event.total) * 100)
}
</script>

<template>

  <div>
    <!--上传组件-->
    <el-upload
        :auto-upload="false"
        :on-change="handleChange"
        :before-upload="handleBeforeUpload"
        :on-progress="handleProgress"
    >
      <el-button slot="trigger">选取文件</el-button>
      <!--上传文件按钮-->

      <!--      <div class="clearfix"></div>-->

    </el-upload>
    <el-button style="margin-left: 10px" type="primary" :loading="uploading" :disabled="files.length === 0"
               @click="handleUpload">
      上传文件
    </el-button>
    <el-progress :percentage="percent"></el-progress>
  </div>
</template>

<style scoped>

</style>
